﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Data.Objects;
using System.Security.Cryptography;
using System.Data.Objects.DataClasses;
using System.Drawing;
using System.Linq;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using PasswordManager.Classes;
using Gma.UserActivityMonitor;


namespace PasswordManager
{
    public partial class Form1 : Form
    {
        bool uncrypted = false;
        bool ctrlDown  =false;
        bool altDown   =false;
        bool fixingSelectionFlag = false;
        bool shiftDown = false;
        public TreeNode moved;
        public Results r = new Results();
        public Node Selected { get; set; }
        private List<string> Words { get; set; }
        public List<Guid> Ids { get; set; }

        public Form1()
        {
            InitializeComponent();
        }

        #region "Others"

        public Node GetNode(string id)
        {
            Guid g = new Guid(id);
            Node n = (Node)PasswordStorage._db[g];
            return n;
        }

        private bool CheckItOut(Node cred)
        {
            bool flag = false;
            foreach (string word in this.Words)
            {
                string upperWord = word.ToUpper();
                string title = cred.Title.ToUpper();
                string username = cred.Username.ToUpper();
                string password = cred.Password.ToUpper();
                string additional = cred.Addition.ToUpper();
                string description = cred.Description.ToUpper();

                if (!string.IsNullOrEmpty(title) && title.Contains(upperWord))
                {
                    flag = true;
                    break;
                }
                if (!string.IsNullOrEmpty(username) && username.Contains(upperWord))
                {
                    flag = true;
                    break;
                }
                if (!string.IsNullOrEmpty(password) && password.Contains(upperWord))
                {
                    flag = true;
                    break;
                }
                if (!string.IsNullOrEmpty(additional) && additional.Contains(upperWord))
                {
                    flag = true;
                    break;
                }
                if (!string.IsNullOrEmpty(description) && description.Contains(upperWord))
                {
                    flag = true;
                    break;
                }

            }
            return flag;
        }

        private void UnMarkTree(TreeNodeCollection treenodes)
        {
            foreach (TreeNode treenode in treenodes)
            {
                if (treenode.ForeColor == Color.Red)
                {
                    treenode.ForeColor = Color.Black;
                }
                //treenode.Collapse();
                if (treenode.Nodes.Count != 0)
                {
                    UnMarkTree(treenode.Nodes);
                }
            }

        }

        private void FindWords(object sender, EventArgs e)
        {
            UnMarkTree(treeView1.Nodes);
            treeView1.Refresh();
            treeView1.Invalidate();
            string words = textBox_toFind.Text;
            string[] separated = words.Split(new char[]{' ','\n', '\r'}, StringSplitOptions.RemoveEmptyEntries);


            this.Words = separated.ToList();
            List<RowOfResult> list = new List<RowOfResult>();

            foreach (DictionaryEntry d in PasswordStorage._db)
            {
                Node node = (Node)d.Value;
                if (CheckItOut(node))
                {
                    list.Add(new RowOfResult() { Name = node.Title+" ("+node.Username+")", Id=node.NodeId });
                    this.Ids.Add(node.NodeId);
                }
            }

            dataGridView_results.DataSource = list;
            dataGridView_results.Columns[0].Visible = false;
            MarkTree(treeView1.Nodes);
            //tabControl1.SelectedIndex = 0;

            

            
            /*dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells.Add(c);
            dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells.Add("copy");
            dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells.Add("goto");*/

        }

        public void MarkTree(TreeNodeCollection treenodes)
        {
            foreach (TreeNode treenode in treenodes)
            {
                if (this.Ids.Contains(new Guid(treenode.Tag.ToString())))
                {
                    treenode.ForeColor = Color.Red;
                    TreeNode parent = treenode.Parent;
                    while (parent != null)
                    {
                        parent.Expand();
                        parent = parent.Parent;
                    }                    
                }
                if (treenode.Nodes.Count != 0)
                {
                    MarkTree(treenode.Nodes);
                }
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            timer1.Interval = 60000;            
            notifyIcon1.Visible = false;
            notifyIcon1.Text = "Password manager";
            this.Ids = new List<Guid>();
            this.Words = new List<string>();
            ImageList i = new ImageList();
            i.ImageSize = new Size(25, 25);
            i.Images.Add(PasswordManager.Properties.Resources.folder);
            i.Images.Add(PasswordManager.Properties.Resources.credentials);
            i.ColorDepth = ColorDepth.Depth32Bit;
            treeView1.ImageList = i;            
            treeView1.Scrollable = true;
        }

        void HookManager_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode.ToString() == "LControlKey")
            {
                ctrlDown = false;
            }
            else
            {
                if (e.KeyCode.ToString() == "LMenu")
                {
                    altDown = false;
                }
                else
                {
                    if (e.KeyCode.ToString() == "LShiftKey")
                    {
                        shiftDown = false;
                    }
                }
            }
        }

        void HookManager_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode.ToString()=="LControlKey")
            {
                ctrlDown=true;
            }
            else
            {
                if (e.KeyCode.ToString()=="LMenu")
                {
                    altDown=true;
                }
                else
                {
                    if (e.KeyCode.ToString()=="LShiftKey")
                    {
                        shiftDown=true;
                    }
                    else
                    {
                        string hotkey = e.KeyData.ToString();
                        if (ctrlDown && altDown && shiftDown)
                        {
                            if(hotkey=="Z")
                            {
                                this.ShowInTaskbar = true;
                                this.Visible = true;                                
                                notifyIcon1.Visible = false;
                            }
                        }
                    }
                }
            }

        }

        private void tabPage3_Enter(object sender, EventArgs e)
        {
            treeView1.Invalidate();
            treeView1.Refresh();
        }
        private string GeneratePassword()
        {
            Random r = new Random();
            string newPassword = "";
            string alphanumerical = "_qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789";
            string special = "\"'\\/#.,!@$%^&*()";
            int length = r.Next(10, 20);
            DialogResult res = MessageBox.Show("Only alphanumerical?", "What password do you need?", MessageBoxButtons.YesNo);
            if (res == System.Windows.Forms.DialogResult.Yes)
            {
                for (int i = 0; i < length; i++)
                {
                    newPassword += alphanumerical[r.Next(alphanumerical.Length)];
                }
            }

            if (res == System.Windows.Forms.DialogResult.No)
            {
                int specialLength = r.Next(2, 5);
                int alphanumericalLength = length - specialLength;
                for (int i = 0; i < length; i++)
                {
                    if (specialLength == 0)
                    {
                        newPassword += alphanumerical[r.Next(alphanumerical.Length)];
                        continue;
                    }
                    if (alphanumericalLength == 0)
                    {
                        newPassword += special[r.Next(special.Length)];
                        continue;
                    }
                    bool switcher = r.Next(0, 2) == 0 ? true : false;
                    if (switcher)
                    {
                        newPassword += alphanumerical[r.Next(alphanumerical.Length)];
                        alphanumericalLength--;
                    }
                    else
                    {
                        newPassword += special[r.Next(special.Length)];
                        specialLength--;
                    }
                }
            }
            return newPassword;
        }

        #endregion

        #region "Buttons"

        private void button4_Click(object sender, EventArgs e)
        {
            int f = 0;
        }

        private void button6_Click(object sender, EventArgs e)
        {
            textBox_password.Text = this.Selected.Password;
        }

        private void GeneratePassword_ButtonClick(object sender, EventArgs e)
        {
            string newPassword = GeneratePassword();
            this.Selected.Password = newPassword;
            Clipboard.SetText(newPassword);
        }

        private void SaveChanges_ButtonClick(object sender, EventArgs e)
        {
            this.Selected.Title = textBox_title.Text;
            this.Selected.Username = textBox_username.Text;
            if (textBox_password.Text != "***************")
            {
                this.Selected.Password = textBox_password.Text;
            }
            this.Selected.Description = textBox_description.Text;
            this.Selected.Addition = textBox_additional.Text;
            textBox_password.Text = "***************";
            PasswordStorage.Changed = true;
        }

        #endregion

        #region "TreeView functions"

        private void treeView1_BeforeSelect(object sender, TreeViewCancelEventArgs e)
        {
            Guid g = new Guid(e.Node.Tag.ToString());
            Node selected = (Node)PasswordStorage._db[g];
            textBox_title.Text = selected.Title;
            textBox_username.Text = selected.Username;
            if (!string.IsNullOrEmpty(selected.Password))
            {
                textBox_password.Text = "***************";
            }
            else
            {
                textBox_password.Text = "";
            }
            textBox_description.Text = selected.Description;
            textBox_additional.Text = selected.Addition;
            this.Selected = selected;
        }

        private void treeView1_ItemDrag(object sender, ItemDragEventArgs e)
        {
            moved = (TreeNode)e.Item;
            DoDragDrop(e.Item.ToString(), DragDropEffects.Move | DragDropEffects.Copy);
        }

        private void treeView1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.Text))
            {
                e.Effect = DragDropEffects.Move;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        private void treeView1_DragDrop(object sender, DragEventArgs e)
        {
            Point pos = treeView1.PointToClient(new Point(e.X, e.Y));
            TreeNode targetNode = treeView1.GetNodeAt(pos);
            TreeNode nodeCopy;

            if (targetNode != null)
            {
                var newParent = new Guid();
                nodeCopy = new TreeNode(moved.Text);
                nodeCopy.SelectedImageIndex = moved.SelectedImageIndex;
                nodeCopy.ImageIndex = moved.ImageIndex;
                nodeCopy.Tag = moved.Tag;
                nodeCopy = (TreeNode)moved.Clone();
                if (GetNode(targetNode.Tag.ToString()).Type == "Folder")
                {
                    targetNode.Nodes.Add(nodeCopy);
                    newParent = new Guid(targetNode.Tag.ToString());
                }
                else
                {
                    if (targetNode.Parent != null)
                    {
                        targetNode.Parent.Nodes.Insert(targetNode.Index + 1, nodeCopy);
                    }
                    else
                    {
                        treeView1.Nodes.Insert(targetNode.Index + 1, nodeCopy);
                    }
                    
                    try
                    {
                        newParent = new Guid(targetNode.Parent.Tag.ToString());
                    }
                    catch { }
                }

                if (newParent == new Guid())
                {
                    GetNode(nodeCopy.Tag.ToString()).ParentId = null;
                }
                else
                {
                    GetNode(nodeCopy.Tag.ToString()).ParentId = newParent.ToString();
                }
                treeView1.SelectedNode = nodeCopy;                
                moved.Remove();
                treeView1.Invalidate();
            }
        }

        private void treeView1_DoubleClick(object sender, EventArgs e)
        {
            if (treeView1.SelectedNode == null)
            {
                return;
            }
            if (treeView1.SelectedNode.ImageIndex == 1)
            {
                Guid g = new Guid(treeView1.SelectedNode.Tag.ToString());
                Node credentials = (Node)PasswordStorage._db[g];
                string password = credentials.Password;
                Clipboard.SetText(password);
            }
        }

        #endregion                

        #region "Crypting service"

        public static string EncryptString(string Message, string Passphrase)
        {
            byte[] Results;
            System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();

            // Step 1. We hash the passphrase using MD5
            // We use the MD5 hash generator as the result is a 128 bit byte array
            // which is a valid length for the TripleDES encoder we use below

            MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
            byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));

            // Step 2. Create a new TripleDESCryptoServiceProvider object
            TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();

            // Step 3. Setup the encoder
            TDESAlgorithm.Key = TDESKey;
            TDESAlgorithm.Mode = CipherMode.ECB;
            TDESAlgorithm.Padding = PaddingMode.PKCS7;

            // Step 4. Convert the input string to a byte[]
            byte[] DataToEncrypt = UTF8.GetBytes(Message);

            // Step 5. Attempt to encrypt the string
            //try
            //{
                ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor();
                Results = Encryptor.TransformFinalBlock(DataToEncrypt, 0, DataToEncrypt.Length);
            //}
            //finally
            //{
                // Clear the TripleDes and Hashprovider services of any sensitive information
                TDESAlgorithm.Clear();
                HashProvider.Clear();
            //}

            // Step 6. Return the encrypted string as a base64 encoded string
            return Convert.ToBase64String(Results);
        }

        public static string DecryptString(string Message, string Passphrase)
        {
            byte[] Results;
            string decrypted = "";
            System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();

            // Step 1. We hash the passphrase using MD5
            // We use the MD5 hash generator as the result is a 128 bit byte array
            // which is a valid length for the TripleDES encoder we use below

            MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
            byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));

            // Step 2. Create a new TripleDESCryptoServiceProvider object
            TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();

            // Step 3. Setup the decoder
            TDESAlgorithm.Key = TDESKey;
            TDESAlgorithm.Mode = CipherMode.ECB;
            TDESAlgorithm.Padding = PaddingMode.PKCS7;

            //try
            //{
            // Step 4. Convert the input string to a byte[]
            byte[] DataToDecrypt = Convert.FromBase64String(Message);

            // Step 5. Attempt to decrypt the string
            //try
            //{
                ICryptoTransform Decryptor = TDESAlgorithm.CreateDecryptor();
                Results = Decryptor.TransformFinalBlock(DataToDecrypt, 0, DataToDecrypt.Length);
                decrypted = UTF8.GetString(Results);
            //}
            //catch { }
            //finally
            //{
                // Clear the TripleDes and Hashprovider services of any sensitive information
                TDESAlgorithm.Clear();
                HashProvider.Clear();
            //}

            // Step 6. Return the decrypted string in UTF8 format

            return decrypted;
        }


        #endregion

        #region "Menu and File operations"

        private void Menu_SaveAs(object sender, EventArgs e)
        {
            if (treeView1.Nodes.Count == 0)
            {
                return;
            }
            Point p = new Point(100, 100);
            AddFolder a = new AddFolder(this.PointToScreen(p));

            if (string.IsNullOrEmpty(PasswordStorage.Password))
            {
                a.Text = "Create password for new database";
                a.ShowDialog();
                if (string.IsNullOrEmpty(a.FolderName))
                {
                    return;
                }
                PasswordStorage.Password = a.FolderName;
            }

            saveFileDialog1.FileName = "";
            saveFileDialog1.ShowDialog();
            if (string.IsNullOrEmpty(saveFileDialog1.FileName))
            {
                return;
            }
            FileInfo fileInfo = new FileInfo(saveFileDialog1.FileName);
            PasswordStorage.FullName = saveFileDialog1.FileName;
            PasswordStorage.Salt = fileInfo.Name;

            Save();

            if (!timer1.Enabled)
            {
                timer1.Start();
            }
        }

        public void Clear()
        {
            AutoSave();
            this.label_datetime.Text = "";
            PasswordStorage._db.Clear();
            PasswordStorage.Changed = false;
            PasswordStorage.FullName = "";
            PasswordStorage.Password = "";
            PasswordStorage.Salt = "";
            treeView1.Nodes.Clear();
        }

        private void Menu_OpenDatabase(object sender, EventArgs e)
        {
            this.Clear();
            openFileDialog1.FileName = "";
            openFileDialog1.ShowDialog();
            string filename = openFileDialog1.FileName;
            if (string.IsNullOrEmpty(filename))
            {
                return;
            }
            FileInfo customInfo = new FileInfo(filename);
            PasswordStorage.FullName = openFileDialog1.FileName;
            PasswordStorage.Salt = customInfo.Name;

            Point p = new Point(100, 100);
            AddFolder a = new AddFolder(this.PointToScreen(p));
            a.Text = "Enter password";
            a.textBox_folderName.UseSystemPasswordChar = true;
            if (this.uncrypted == false)
            {
                a.ShowDialog();
                PasswordStorage.Password = a.FolderName;
            }

            XmlDocument xmlDoc = new XmlDocument();

            string crypted = File.ReadAllText(filename);
            string decrypted;
            if (this.uncrypted == false)
            {
                try
                {
                    decrypted = DecryptString(crypted, PasswordStorage.Password + PasswordStorage.Salt);
                }
                catch
                {
                    MessageBox.Show("Wrong password","Error");
                    return;
                }
            }
            else
            {
                decrypted = crypted;
            }
            if (!string.IsNullOrEmpty(decrypted))
            {
                xmlDoc.InnerXml = decrypted;
                LoadTree(xmlDoc.ChildNodes[0].ChildNodes, null);
                timer1.Start();
            }
            if (!string.IsNullOrEmpty(xmlDoc.ChildNodes[0].NamespaceURI))
            {
                label_datetime.Text = string.Format("Last modified: {0}", xmlDoc.ChildNodes[0].NamespaceURI);
            }
        }

        private void Menu_CreateDatabase(object sender, EventArgs e)
        {
            treeView1.Nodes.Clear();
            PasswordStorage.FullName = "";
            PasswordStorage.Password = "";
            PasswordStorage.Salt = "";
            PasswordStorage._db.Clear();


            Point p = new Point(100, 100);
            AddFolder a = new AddFolder(this.PointToScreen(p));
            a.Text = "Create password for new database";
            a.ShowDialog();
            if (string.IsNullOrEmpty(a.FolderName))
            {
                MessageBox.Show("Empty password is not allowed", "Error");
                return;
            }
            PasswordStorage.Password = a.FolderName;

        }

        private void SaveTree(TreeNodeCollection list,XmlNode root,XmlDocument xmlDoc)
        {
            foreach (TreeNode treenode in list)
            {
                Guid g = new Guid(treenode.Tag.ToString());
                Node nodeStored = (Node)PasswordStorage._db[g];
                XmlNode newNode = xmlDoc.CreateNode(XmlNodeType.Element, "Node", nodeStored.NodeId.ToString());
                XmlNode title = xmlDoc.CreateNode(XmlNodeType.Element, "Title", nodeStored.Title);
                XmlNode username = xmlDoc.CreateNode(XmlNodeType.Element, "Username", nodeStored.Username);
                XmlNode passwordNode = xmlDoc.CreateNode(XmlNodeType.Element, "Password", nodeStored.Password);
                XmlNode description = xmlDoc.CreateNode(XmlNodeType.Element, "Description", nodeStored.Description);
                XmlNode addition = xmlDoc.CreateNode(XmlNodeType.Element, "Addition", nodeStored.Addition);
                XmlNode parent = xmlDoc.CreateNode(XmlNodeType.Element, "ParentId", nodeStored.ParentId);
                XmlNode type = xmlDoc.CreateNode(XmlNodeType.Element, "Type", nodeStored.Type);
                newNode.AppendChild(title);
                newNode.AppendChild(username);
                newNode.AppendChild(passwordNode);
                newNode.AppendChild(description);
                newNode.AppendChild(addition);
                newNode.AppendChild(parent);
                newNode.AppendChild(type);
                root.AppendChild(newNode);
                if (treenode.Nodes.Count != 0)
                {
                    XmlNode children = xmlDoc.CreateNode(XmlNodeType.Element, "Children", "");
                    newNode.AppendChild(children);
                    SaveTree(treenode.Nodes, children, xmlDoc);
                }
            }
        }

        private void LoadTree(XmlNodeList nodes, TreeNode root)
        {
            foreach (XmlNode node in nodes)
            {
                Node toStorage = new Node
                {
                    NodeId = new Guid(node.NamespaceURI),
                    Title = node.ChildNodes[0].NamespaceURI,
                    Username = node.ChildNodes[1].NamespaceURI,
                    Password = node.ChildNodes[2].NamespaceURI,                    
                    Description = node.ChildNodes[3].NamespaceURI,
                    Addition = node.ChildNodes[4].NamespaceURI,
                    ParentId = node.ChildNodes[5].NamespaceURI,
                    Type = node.ChildNodes[6].NamespaceURI
                };

                PasswordStorage._db.Add(toStorage.NodeId, toStorage);
                TreeNode added = null;
                if (toStorage.Type == "Folder")
                {
                    if (root == null)
                    {
                        added = treeView1.Nodes.Add("", toStorage.Title, 0);
                    }
                    else
                    {
                        added = root.Nodes.Add("", toStorage.Title, 0);
                    }
                    added.SelectedImageIndex = 0;
                    if (node.ChildNodes[7] != null)
                    {
                        LoadTree(node.ChildNodes[7].ChildNodes, added);
                    }                    
                }
                else
                {
                    if (root == null)
                    {
                        added = treeView1.Nodes.Add("", toStorage.Title + " (" + toStorage.Username + ")", 1);
                    }
                    else
                    {
                        added = root.Nodes.Add("", toStorage.Title + " (" + toStorage.Username + ")", 1);
                    }
                    added.SelectedImageIndex = 1;
                }
                added.Tag = toStorage.NodeId;
            }
        }

        public string AutoSave()
        {
            if (PasswordStorage._db.Count == 0)
            {
                return "ok";
            }

            if (string.IsNullOrEmpty(PasswordStorage.Password) || string.IsNullOrEmpty(PasswordStorage.FullName))
            {
                timer1.Stop();
                DialogResult res = MessageBox.Show("Do you want to save database?", "Wait a minute...", MessageBoxButtons.YesNoCancel);
                if (res == System.Windows.Forms.DialogResult.No)
                {
                    return "no";
                }
                if (res == System.Windows.Forms.DialogResult.Cancel)
                {
                    return "cancel";
                }
            }
            Point p = new Point(100, 100);
            AddFolder a = new AddFolder(this.PointToScreen(p));

            if (string.IsNullOrEmpty(PasswordStorage.Password))
            {
                a.Text = "Create password for new database";
                a.ShowDialog();
                if (string.IsNullOrEmpty(a.FolderName))
                {
                    return "cancel";
                }
                PasswordStorage.Password = a.FolderName;
            }

            if (string.IsNullOrEmpty(PasswordStorage.FullName))
            {
                saveFileDialog1.ShowDialog();
                if (string.IsNullOrEmpty(saveFileDialog1.FileName))
                {
                    return "cancel";
                }
                PasswordStorage.FullName = saveFileDialog1.FileName;
                FileInfo fileInfo = new FileInfo(saveFileDialog1.FileName);
                PasswordStorage.Salt = fileInfo.Name;
            }

            Save();
            return "ok";
        }

        private void Save()
        {
            XmlDocument xmlDoc = new XmlDocument();
            XmlNode root;
            if (PasswordStorage.Changed == false)
            {
                return;                
            }
            
            root = xmlDoc.CreateNode(XmlNodeType.Element, "root", DateTime.Now.ToString());
            xmlDoc.AppendChild(root);

            SaveTree(treeView1.Nodes, root, xmlDoc);

            string toSave = "";
            if (this.uncrypted)
            {
                toSave = xmlDoc.InnerXml;
            }
            else
            {
                toSave = EncryptString(xmlDoc.InnerXml, PasswordStorage.Password + PasswordStorage.Salt);
            }

            File.WriteAllText(PasswordStorage.FullName, toSave);
            PasswordStorage.Changed = false;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            string res = AutoSave();
            if (res == "cancel")
            {
                e.Cancel = true;
            }
        }

        #endregion

        #region "Context menu"

        private void ContextMenu_Open(object sender, CancelEventArgs e)
        {
            Point pos = treeView1.PointToClient(new Point(MousePosition.X, MousePosition.Y));
            TreeNode targetNode = treeView1.GetNodeAt(pos);
            if (targetNode == null)
            {
                this.fixingSelectionFlag = true;
            }
            else
            {
                treeView1.SelectedNode = targetNode;
            }
            
            if (treeView1.SelectedNode == null)
            {
                contextMenuStrip1.Items[2].Visible = false;
            }
            else
            {
                contextMenuStrip1.Items[2].Visible = true;
            }
        }

        private void ContextMenu_Delete(object sender, EventArgs e)
        {
            Guid g = new Guid(treeView1.SelectedNode.Tag.ToString());
            Node toDelete = (Node)PasswordStorage._db[g];
            DialogResult res = MessageBox.Show("Do you really wanna delete " + toDelete.Title + "?", "Deleting", MessageBoxButtons.YesNo);
            if (res == System.Windows.Forms.DialogResult.Yes)
            {
                if (toDelete.Type == "Folder")
                {
                    res = MessageBox.Show(toDelete.Title + " is a folder, all content will be removed also. Do you wanna continue?", "But it's a folder!", MessageBoxButtons.YesNo);
                    if (res == System.Windows.Forms.DialogResult.No)
                    {
                        return;
                    }
                }
                treeView1.SelectedNode.Remove();
                PasswordStorage._db.Remove(g);
                PasswordStorage.Changed = true;
            }
        }

        private void ContextMenu_AddFolder(object sender, EventArgs e)
        {
            Point p = new Point(100, 100);
            AddFolder a = new AddFolder(this.PointToScreen(p));
            a.ShowDialog();
            if (a.FolderName == null)
            {
                return;
            }
            string folderName = a.FolderName;
            Node newFolder = new Node();
            newFolder.NodeId = Guid.NewGuid();
            newFolder.Title = folderName;
            newFolder.Type = "Folder";

            if ((this.fixingSelectionFlag == false) && (GetNode(treeView1.SelectedNode.Tag.ToString()).Type == "Folder"))
            {
                newFolder.ParentId = treeView1.SelectedNode.Tag.ToString();
                TreeNode added = treeView1.SelectedNode.Nodes.Add(folderName);
                added.ImageIndex = 0;
                added.SelectedImageIndex = 0;
                added.Tag = newFolder.NodeId.ToString();
            }
            else
            {
                if ((this.fixingSelectionFlag == true) || (treeView1.SelectedNode.Parent == null))
                {
                    newFolder.ParentId = null;
                    int index = 0;
                    if (this.fixingSelectionFlag == false)
                    {
                        index = treeView1.SelectedNode.Index;
                    }
                    TreeNode added = treeView1.Nodes.Insert(index, folderName);
                    added.Tag = newFolder.NodeId.ToString();
                    added.ImageIndex = 0;
                    added.SelectedImageIndex = 0;
                    this.fixingSelectionFlag = false;
                }
                else
                {
                    newFolder.ParentId = treeView1.SelectedNode.Parent.Tag.ToString();
                    TreeNode added = treeView1.SelectedNode.Parent.Nodes.Add(folderName);
                    added.Tag = newFolder.NodeId.ToString();
                    added.ImageIndex = 0;
                    added.SelectedImageIndex = 0;
                }
            }
            PasswordStorage._db.Add(newFolder.NodeId, newFolder);
            PasswordStorage.Changed = true;
            if (treeView1.SelectedNode != null)
            {
                treeView1.SelectedNode.Expand();
            }
            treeView1.Refresh();
            treeView1.Invalidate();
        }

        private void ContextMenu_AddCredentials(object sender, EventArgs e)
        {
            AddCredentials a = new AddCredentials();
            a.ShowDialog();
            Node newCredentials = a.NewCredentials;
            TreeNode t = new TreeNode(newCredentials.Title);
            if ((this.fixingSelectionFlag == false) && (GetNode(treeView1.SelectedNode.Tag.ToString()).Type == "Folder"))
            {
                newCredentials.ParentId = treeView1.SelectedNode.Tag.ToString();
                TreeNode added = treeView1.SelectedNode.Nodes.Insert(0, newCredentials.Title + " (" + newCredentials.Username + ")");
                added.SelectedImageIndex = 1;
                added.ImageIndex = 1;
                added.Tag = newCredentials.NodeId;
            }
            else
            {
                if ((this.fixingSelectionFlag == true) || (treeView1.SelectedNode.Parent == null))
                {
                    newCredentials.ParentId = null;
                    int index = 0;
                    if (this.fixingSelectionFlag==false)
                    {
                        index = treeView1.SelectedNode.Index;
                    }
                    TreeNode added = treeView1.Nodes.Insert(index, newCredentials.Title+" ("+newCredentials.Username+")");
                    added.SelectedImageIndex = 1;
                    added.ImageIndex = 1;
                    added.Tag = newCredentials.NodeId;
                    this.fixingSelectionFlag = false;
                }
                else
                {
                    newCredentials.ParentId = treeView1.SelectedNode.Parent.Tag.ToString();
                    TreeNode added = treeView1.SelectedNode.Parent.Nodes.Insert(treeView1.SelectedNode.Index, newCredentials.Title + " (" + newCredentials.Username + ")");
                    added.SelectedImageIndex = 1;
                    added.ImageIndex = 1;
                    added.Tag = newCredentials.NodeId;
                }
            }
            PasswordStorage._db.Add(newCredentials.NodeId, newCredentials);
            PasswordStorage.Changed = true;
            treeView1.Refresh();
            treeView1.Invalidate();
        }

        #endregion

        private void ToTray(object sender, EventArgs e)
        {
            this.Visible = false;
            notifyIcon1.Visible = true;
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.Visible = true;
            notifyIcon1.Visible = false;
            this.WindowState = FormWindowState.Normal;
            HookManager.KeyDown -= new KeyEventHandler(HookManager_KeyDown);
            HookManager.KeyUp -= new KeyEventHandler(HookManager_KeyUp);
        }

        private void Copy_ButtonClick(object sender, EventArgs e)
        {
            Clipboard.SetText(this.Selected.Password);
        }

        private void Menu_CreateUncryptedCopy(object sender, EventArgs e)
        {
            if (treeView1.Nodes.Count == 0)
            {
                return;
            }
            Point p = new Point(100, 100);
            AddFolder a = new AddFolder(this.PointToScreen(p));
            a.Text = "Enter password";
            a.textBox_folderName.PasswordChar = '*';
            if (!string.IsNullOrEmpty(PasswordStorage.Password))
            {
                a.ShowDialog();
            }
            else
            {
                a.FolderName = null;
            }
            
            if (a.FolderName == PasswordStorage.Password)
            {
                saveFileDialog1.FileName = "";
                saveFileDialog1.ShowDialog();
                if (string.IsNullOrEmpty(saveFileDialog1.FileName))
                {
                    return;
                }
                string temp = PasswordStorage.FullName;
                PasswordStorage.FullName = saveFileDialog1.FileName;
                this.uncrypted = true;
                PasswordStorage.Changed = true;
                Save();
                this.uncrypted = false;
                PasswordStorage.FullName = temp;
            }
            else
            {
                MessageBox.Show("Wrong password", "Error");
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {

            AutoSave();
            timer1.Start();
            altDown = false;
            ctrlDown = false;
            shiftDown = false;
        }

        private void Menu_changePassword(object sender, EventArgs e)
        {
            if (treeView1.Nodes.Count == 0)
            {
                return;
            }
            Point p = new Point(100, 100);
            ChangePassword c = new ChangePassword(PasswordStorage.Password,this.PointToScreen(p));
            c.ShowDialog();
            if (!string.IsNullOrEmpty(c.NewPassword))
            {
                PasswordStorage.Password = c.NewPassword;
                AutoSave();
            }
        }

        private void Menu_LoadUncryptedCopy(object sender, EventArgs e)
        {
            AutoSave();
            this.uncrypted = true;
            Menu_OpenDatabase(new object(), new EventArgs());
            this.uncrypted = false;
            PasswordStorage.Changed = true;
        }

        private void Menu_about(object sender, EventArgs e)
        {
            Point p = new Point(100, 100);
            About a = new About(this.PointToScreen(p));
            a.ShowDialog();            

        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                HookManager.KeyDown += new KeyEventHandler(HookManager_KeyDown);
                HookManager.KeyUp += new KeyEventHandler(HookManager_KeyUp);
                ToTray(new object(), new EventArgs());
            }
        }

        private void Menu_howTo(object sender, EventArgs e)
        {
            Point p = new Point(100, 100);
            HowTo h = new HowTo(this.PointToScreen(p));
            h.ShowDialog();
        }

        private void dataGridView_results_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            DataGridViewCell c = dataGridView_results.Rows[e.RowIndex].Cells[e.ColumnIndex];
            string data = dataGridView_results.Rows[e.RowIndex].Cells[1].Value.ToString();
            Guid g = (Guid) dataGridView_results.Rows[e.RowIndex].Cells[0].Value;
            Node n = (Node)PasswordStorage._db[g];
            if (c.Value.ToString() == "Copy password")
            {
                Clipboard.SetText(n.Password);
            }
            if (c.Value.ToString() == "Go to record")
            {
                GoToNode(treeView1.Nodes, n.NodeId.ToString());
                tabControl1.SelectedIndex = 0;
            }
        }

        private void GoToNode(TreeNodeCollection treenodes, string id)
        {
            foreach (TreeNode treenode in treenodes)
            {
                if (treenode.Tag.ToString()==id)
                {
                    treeView1.SelectedNode = treenode;
                    return;
                }
                if (treenode.Nodes.Count != 0)
                {
                    GoToNode(treenode.Nodes, id);
                }
            }

        }
    }
}
